// 2、尝试理解Vue 3.0中对各类依赖是如何存储的，我们要如何正确的管理这些依赖呢？
// 假设我们现在拥有了一个商品对象，它的属性记录了价格和数量信息，情况比1中会好一些吗？

import { log } from "./shared";

const targetMap: TargetMap = new WeakMap(); // 全局映射：响应式对象--->属性依赖集合

// 对象属性依赖收集
function track(targetMap: TargetMap, target: any, key: string) {
  let depMap: DepMap | undefined = targetMap.get(target); // 哈希表(集合)： 属性--->依赖队列
  // 如果不存在集合那就新建一个哈希表并赋值
  if (!depMap) {
    depMap = new Map();
    targetMap.set(target, depMap);
  }
  let dep: Dep | undefined = depMap.get(key); // 依赖队列
  // 如果不存在依赖队列就新建一个集合并赋值
  if (!dep) {
    dep = new Set();
    depMap.set(key, dep);
  }
  dep.add(effect); // 添加进需要依赖的函数，源码中为effect
}

// 对象属性依赖触发更新
function trigger(targetMap: TargetMap, target: any, key: string) {
  const depMap: DepMap | undefined = targetMap.get(target);
  if (!depMap) return; // 对象不存在依赖集合就直接返回
  const dep: Dep | undefined = depMap.get(key);
  // 对象属性存在依赖就更新所有依赖
  if (dep) {
    dep.forEach((effect) => {
      effect();
    });
  }
}

// 依赖的函数
const effect = () => {
  total = product.price * product.quantity;
};



// 测试用例2
let product: ProductInfo = {
  price: 5,
  quantity: 10,
}; // 商品对象
let total:number = 0; // 总价
track(targetMap, product, "price");// 已经将effect依赖函数追踪存储
effect();// 运行第一次
log(total); // 50
product.price = 10;
log(total); // 50，不会变化
trigger(targetMap, product, "price");
log(total); // 100，触发依赖更新，发生变化

// 现在对依赖的管理是不是好很多且更加系统了，但我们仍然需要手动命令式的去触发track和trigger
// 当然实际上Vue3.0源码中的依赖管理机制远比这个复杂，涉及到多个Map哈希表的映射，例如rawToReact、reactToRaw
